﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Zero.UControl.Component.Common
{
    public static class HttpDownloader
    {
        private static readonly HttpClient httpClient = new HttpClient
        {
            Timeout = TimeSpan.FromMinutes(30)
        };

        public static void SetHeaders(Dictionary<string, string> headers)
        {
            if (headers != null)
            {
                foreach (var header in headers)
                {
                    httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
                }
            }
        }

        /// <summary>
        /// 异步下载文件
        /// </summary>
        /// <param name="url">下载地址</param>
        /// <param name="savePath">保存路径（含文件名）</param>
        /// <param name="progress">下载进度回调（0-100）</param>
        /// <param name="cancellationToken">取消下载的令牌</param>
        /// <returns></returns>
        public static async Task DownloadFileAsync(string url, string savePath, IProgress<double>? progress = null, CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrWhiteSpace(url))
                throw new ArgumentException("URL 不能为空。", nameof(url));
            if(!Directory.Exists(Path.GetDirectoryName(savePath)))
                Directory.CreateDirectory(Path.GetDirectoryName(savePath));
            
            using var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
            response.EnsureSuccessStatusCode();

            var totalBytes = response.Content.Headers.ContentLength ?? -1L;
            var canReportProgress = totalBytes > 0 && progress != null;

            await using var contentStream = await response.Content.ReadAsStreamAsync(cancellationToken);
            await using var fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);

            var buffer = new byte[8192];
            long totalRead = 0;
            int read;

            while ((read = await contentStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
            {
                await fileStream.WriteAsync(buffer.AsMemory(0, read), cancellationToken);
                totalRead += read;

                if (canReportProgress)
                {
                    double percent = (totalRead * 1.0 / totalBytes) * 100;
                    progress?.Report(Math.Round(percent, 2));
                }
            }
        }

        /// <summary>
        /// 下载字符串内容（如 JSON / HTML / 文本）
        /// </summary>
        public static async Task<string> DownloadStringAsync(string url, CancellationToken cancellationToken = default)
        {
            using var response = await httpClient.GetAsync(url, cancellationToken);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync(cancellationToken);
        }

        /// <summary>
        /// 下载字节数组（适用于二进制数据）
        /// </summary>
        public static async Task<byte[]> DownloadBytesAsync(string url, CancellationToken cancellationToken = default)
        {
            using var response = await httpClient.GetAsync(url, cancellationToken);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsByteArrayAsync(cancellationToken);
        }
    }
}
